package com.basic.common.websocket;

import com.basic.common.core.domain.model.LoginUser;
import com.basic.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import javax.websocket.OnError;
import javax.websocket.Session;
import java.util.concurrent.Semaphore;


/**
 * websocket 事件处理
 *
 * @author zhaoxy_jn@163.com
 */
@Component
public class HttpAuthHandler extends TextWebSocketHandler {

    private static final Logger logger = LoggerFactory.getLogger(HttpAuthHandler.class);

    /**
     * 默认最多允许同时在线人数100
     */
    public static int socketMaxOnlineCount = 100;

    /**
     * 限制同时连接的客户端数量。
     */
    private static final Semaphore socketSemaphore = new Semaphore(socketMaxOnlineCount);

    /**
     * socket 建立成功事件
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        boolean semaphoreFlag = false;
        // 尝试获取信号量
        semaphoreFlag = SemaphoreUtils.tryAcquire(socketSemaphore);
        if (!semaphoreFlag) {
            logger.error("\n 当前在线人数超过限制数- {}", socketMaxOnlineCount);
            // 未获取到信号量
            WebSocketUsers.sendMessageToUserByText(session, "当前在线人数超过限制数：" + socketMaxOnlineCount);
            session.close();
        } else {
            // 添加用户
            Long uid = (Long) session.getAttributes().get("uid");
            LoginUser uInfo = (LoginUser) session.getAttributes().get("uInfo");
            WebSocketUsers.put(uid, session);
            WebSocketUsers.put(uid, uInfo);
            logger.info("\n 当前在线人数 - {}", WebSocketUsers.getUsers().size());
        }
    }

    /**
     * 接收消息事件
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        session.sendMessage(new TextMessage(message.getPayload()));
    }

    /**
     * socket 断开连接时
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
        Long uid = (Long) session.getAttributes().get("uid");
        if (StringUtils.isNotNull(uid)) {
            // 用户退出，移除缓存
            WebSocketUsers.remove(uid);
            WebSocketUsers.removeLoginUser(uid);
            // 释放信号量
            SemaphoreUtils.release(socketSemaphore);
        }
    }

    /**
     * 抛出异常时处理
     */
    @OnError
    public void onError(Session session, Throwable exception) throws Exception {
        if (session.isOpen()) {
            // 关闭连接
            session.close();
        }
        String sessionId = session.getId();
        // 移出用户
        WebSocketUsers.remove(Long.valueOf(sessionId));
        // 获取到信号量则需释放
        SemaphoreUtils.release(socketSemaphore);
        logger.error("\n 连接异常 - {} ，异常信息 - {}", sessionId, exception.getMessage());
    }

}

